/* http://www.apache.org/licenses/LICENSE-2.0 */
/* Many thanks to the writor of libaco Sen Han <00hnes@gmail.com> */

#ifdef __x86_64__
#else
	#error "platform no support yet"
#endif

.text
.globl mco_ctx_switch
.type  mco_ctx_switch, @function
.intel_syntax noprefix
mco_ctx_switch:
/* extern void co_ctx_switch(void * from_reg, void * to_reg); */
/*
	0x00			 -->			   0xff
	eip esp ebp edi esi ebx fpucw16 mxcsr32
	0   4   8   c   10  14  18	  1c
*/
/*
	0x00				  -->				  0xff
	r12 r13 r14 r15 rip rsp rbx rbp fpucw16 mxcsr32
	0   8   10  18  20  28  30  38  40	  44
*/
	// rdi - from_co | rsi - to_co
	mov	 rdx,QWORD PTR [rsp]	  // retaddr
	lea	 rcx,[rsp+0x8]			// rsp
	mov	 QWORD PTR [rdi+0x0], r12
	mov	 QWORD PTR [rdi+0x8], r13
	mov	 QWORD PTR [rdi+0x10],r14
	mov	 QWORD PTR [rdi+0x18],r15
	mov	 QWORD PTR [rdi+0x20],rdx // retaddr
	mov	 QWORD PTR [rdi+0x28],rcx // rsp
	mov	 QWORD PTR [rdi+0x30],rbx
	mov	 QWORD PTR [rdi+0x38],rbp
	fnstcw  WORD PTR  [rdi+0x40]
	stmxcsr DWORD PTR [rdi+0x44]
	mov	 r12,QWORD PTR [rsi+0x0]
	mov	 r13,QWORD PTR [rsi+0x8]
	mov	 r14,QWORD PTR [rsi+0x10]
	mov	 r15,QWORD PTR [rsi+0x18]
	mov	 rax,QWORD PTR [rsi+0x20] // retaddr
	mov	 rcx,QWORD PTR [rsi+0x28] // rsp
	mov	 rbx,QWORD PTR [rsi+0x30]
	mov	 rbp,QWORD PTR [rsi+0x38]
	fldcw   WORD PTR	  [rsi+0x40]
	ldmxcsr DWORD PTR	 [rsi+0x44]
	mov	 rsp,rcx
	jmp	 rax

.globl mco_save_fpucw_mxcsr
.type  mco_save_fpucw_mxcsr, @function
.intel_syntax noprefix
mco_save_fpucw_mxcsr:
	fnstcw  WORD PTR  [rdi]
	stmxcsr DWORD PTR [rdi+0x4]
	ret
